import { spawn } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
import { createClient } from 'redis';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export class PythonPlugin extends plugin {
  static instance = null;

  constructor() {
    if (PythonPlugin.instance) {
      return PythonPlugin.instance;
    }

    super({
      name: 'Yaemiko-plugin',
      dsc: '宫司插件复活了草',
      event: 'message',
      priority: 5000,
      rule: [
        {
          reg: '^#testpy',
          fnc: 'handlePyCommand'
        }
      ]
    });

    PythonPlugin.instance = this;
    this.initialize();

    // 捕获退出信号并调用 unload 方法
    process.on('SIGINT', () => this.unload());
    process.on('SIGTERM', () => this.unload());
  }

  async initialize() {
    console.log('-----------Q-W-Q-----------')
    console.log('Yunzai-Bot & Yaemiko-plugin')
    console.log('Yaemiko-plugin在初始化了捏~')
    console.log('------当前版本v1.0.0------')
    console.log('---------------------------')

    this.initialized = false;
    this.pythonProcess = null;
    this.redisSub = null;
    this.redisPub = null;

    await this.initRedis();
    await this.initPython();

    this.initialized = true;
  }

  async initRedis() {
    if (this.redisSub) {
      await this.redisSub.unsubscribe();
      await this.redisSub.disconnect();
    }
    if (this.redisPub) {
      await this.redisPub.disconnect();
    }

    this.redisSub = createClient({ url: 'redis://127.0.0.1:6379/0' });
    this.redisPub = createClient({ url: 'redis://127.0.0.1:6379/0' });

    const handleError = (type) => (err) =>
      console.error(`[Redis ${type}]`, err);

    this.redisSub.on('error', handleError('订阅端'));
    this.redisPub.on('error', handleError('发布端'));

    await Promise.all([
      this.redisSub.connect(),
      this.redisPub.connect()
    ]);

    await this.redisSub.subscribe('py-response', (message, channel) => {
      if (channel === 'py-response') {
        try {
          const data = JSON.parse(message);
          this.reply(`${data.response}`, { user_id: data.user_id });
        } catch (e) {
          console.error('[Redis] 消息解析失败:', e);
        }
      }
    });
  }

  initPython() {
    if (this.pythonProcess) return;

    const pythonScriptPath = path.join(__dirname, 'python', 'main.py');
    const pythonExecutable = path.join(__dirname, 'runtime', 'python.exe');

    console.log('启动 Python 进程:', pythonExecutable);
    this.pythonProcess = spawn(pythonExecutable, [pythonScriptPath]);

    // 输出处理
    this.pythonProcess.stdout.on('data', (data) => {
      process.stdout.write(`[Python] ${data}`);
    });

    this.pythonProcess.stderr.on('data', (data) => {
      process.stderr.write(`[Python 错误] ${data}`);
    });

    // 进程管理


    // 确保 Python 进程在父进程退出时也被终止
    process.on('exit', () => {
      if (this.pythonProcess) {
        this.pythonProcess.kill('SIGKILL');
      }
    });
  }

  async handlePyCommand(e) {
    if (!this.initialized) {
      return this.reply('插件初始化中，请稍后...', e);
    }

    const command = e.msg.replace('#testpy', '').trim();
    await this.redisPub.publish('py-request', JSON.stringify({
      event: {
        user_id: e.user_id,
        message_type: e.message_type,
        raw_message: e.raw_message,
        sender: e.sender
      },
      command: command
    }));

    return true;
  }

  async unload() {
    this.destroyed = true;

    // 终止 Python 进程
    if (this.pythonProcess) {
      try {
        this.pythonProcess.kill('SIGKILL'); // 强制终止
        console.log('Python 进程已强制终止');
      } catch (err) {
        console.error('无法终止 Python 进程:', err);
      }
      this.pythonProcess = null;
    }

    // 关闭 Redis 订阅客户端
    if (this.redisSub) {
      try {
        await this.redisSub.unsubscribe();
        await this.redisSub.disconnect();
        console.log('Redis 订阅端已关闭');
      } catch (err) {
        console.error('无法关闭 Redis 订阅端:', err);
      }
      this.redisSub = null;
    }

    // 关闭 Redis 发布客户端
    if (this.redisPub) {
      try {
        await this.redisPub.disconnect();
        console.log('Redis 发布端已关闭');
      } catch (err) {
        console.error('无法关闭 Redis 发布端:', err);
      }
      this.redisPub = null;
    }

    // 清理单例实例
    PythonPlugin.instance = null;
  }
}

export function getPlugin() {
  return PythonPlugin.instance || new PythonPlugin();
}
